package com.cskaoyan.javase.oop3.abstract1.exercise4;

/**
 * @description: 小试牛刀abstract
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

import com.sun.org.apache.bcel.internal.classfile.Code;

/**
 *  > 小试牛刀
 *  >
 *  > 我们正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 *  > 公司将员工分为三类，普通员工负责杂项工作，程序员负责技术开发，经理负责统筹规划
 *  > 普通员工包含3个属性：姓名、工号以及工资，行为是工作
 *  > 程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 *  > 经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 *  - 请使用所学的知识设计该员工系统
 *  - 要求类中提供必要的方法进行属性访问（description）
 *
 *  分析：现在系统中有三种员工，这些员工的属性和行为是有重复的地方
 *  一旦有重复，就立刻想到复用，一旦想到复用成员，立刻想到继承
 *  如果直接定义普通员工类，然后让经理，程序员类继承这个类
 *  这样做不好，这就体现了抽象的一个概念
 *  我不希望一个可以创建对象的类去被继承，被直接重写。而是希望有一个抽象的概念来去被继承
 *  并且里面有抽象方法，能够起到占位的作用
 *  普通类无法起到约束 规范的作用，而抽象类可以
 *
 *  注意：抽象类的命名规范，普遍来说抽象类以AbstractXxx开头
 *
 *  对于普通员工和程序员而言 他们的属性是一样的，这样它们访问属性的方法也是一样的
 *  存在复用，于是我们在抽象类种提供默认实现方法
 *
 */
public class Demo {
    public static void main(String[] args) {
        /*//多态来访问
        AbstractStaff as;
        as= new Staff();
        as.work();
        as = new Coder();
        as.work();
        //想加班，这里必须强转成程序员类的引用
        ((Coder) as).overtimeWork();
        as = new Manager();
        as.work();
        //这里想要奖金，也必须强转成经理类的引用
        System.out.println(((Manager) as).bonus);*/

        AbstractStaff as;
        as= new Staff("张三",1,10000);
        as.getDescription();
        as = new Coder("李四",2,20000);
        as.getDescription();
        as = new Manager("麻子",3,30000,100000);
        as.getDescription();
    }
}
//抽象的员工类
abstract class AbstractStaff{
    String name;
    int id;
    double salary;
    public abstract void work();

    //抽象类中的具体方法
    public void getDescription(){
        System.out.println("该员工姓名为："+name+"员工工号是："+id+"工资为："+salary);
    }
    //提供构造方法，给子类初始化用

    public AbstractStaff(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public AbstractStaff() {
    }
}
//普通员工类
class Staff extends AbstractStaff{
    @Override
    public void work() {
        System.out.println("负责杂项工作");
    }

    public Staff(String name, int id, double salary) {
        super(name, id, salary);
    }
    public Staff(){}
}
//定义程序员类
class Coder extends AbstractStaff{
    @Override
    public void work() {
        System.out.println("负责技术开发");
    }
    //程序员额外的行为
    public void overtimeWork(){
        System.out.println(996);
    }
    public Coder(String name, int id, double salary) {
        super(name, id, salary);
    }
    public Coder(){}
}
//定义经理类
class Manager extends AbstractStaff{
    //经理额外的属性
    double bonus;
    @Override
    public void work() {
        System.out.println("负责统筹规划");
    }
    //不满意抽象类中默认实现方法，需要自己重写
    @Override
    public void getDescription() {
        System.out.println("该员工姓名为："+name+"员工工号是："+id+"工资为："+(salary+bonus));
    }

    public Manager(String name, int id, double salary,double bonus) {
        super(name, id, salary); //调用父类有参构造 给父类中的成员赋值
        this.bonus = bonus;//是子类独有的，自己给自己赋值
    }

    public Manager() {
    }
}
class Test extends Manager{
    public Test(){
        //super()
    }
}